#ifndef IANIM_H
#define IANIM_H
#pragma pack(push,1)

#include "matrix.h"
#include "../assetfilemgr.h"
#include "../formats/animformat.h"

//------------------------------------------------------
//	result of an animation
//------------------------------------------------------
class CAnimResult
{
public:
	CVector		rootPos;
	CQuaternion	quatList[64];

public:
	void Blend( u32 nBones, const CAnimResult &from, const CAnimResult &to, f32 frac )
	{
		for( u32 i=0;i<nBones;i++ )
			quatList[i].FastSlerp(from.quatList[i],to.quatList[i],frac);
		rootPos.Lerp(from.rootPos,to.rootPos,frac);
	}
	void Reset()
	{
		rootPos.Set(0.0f,0.0f,0.0f,1.0f);
		for( u32 i=0;i<countof(quatList);i++ )
			quatList[i].Identity();
	}
};


//------------------------------------------------------
//	animation interface
//------------------------------------------------------
class IAnim : public SAnimData
{
public:
	static void	*AssetInit( IAssetFile *pFile, const CMasterIndexEntry *pEntry, void *context );
	static void	AssetUninit( void *ptr, void *context );
	static void	AssetFixup( CAssetFileMgr *pMgr, const IAssetFile *pFile, void *ptr, const CMasterIndexEntry *pEntry );

	static void	Register( CAssetFileMgr *pMgr )
	{
		pMgr->AddAssetType("ANIM",AssetInit,AssetUninit,AssetFixup);
	}

public:

	u32		GetNFrames() const
	{
		return numFrames;
	}
	u32		GetNBones() const
	{
		return numBones;
	}
	u32		GetNTriggers() const
	{
		return numTriggers;
	}

	bool	CheckTrigger( u32 idx, u32 oldFrame, u32 newFrame ) const
	{
		assert(idx<numTriggers);
		return (oldFrame<pTriggers[idx].frameRange[1] && newFrame>=pTriggers[idx].frameRange[0]);
	}

	void	Animate( f32 frameNumber, CAnimResult &result ) const;

};

#pragma pack(pop)
#endif
